﻿/**
*	PhysicsSprite3D
*	@author 	Liam O'Donnell 2008-04-04
**/

package com.spikything.pants3d.objects {
	
	import com.spikything.pants3d.Pants3D;
	import com.spikything.pants3d.core.Physics;
	import com.spikything.pants3d.core.Point3D;
	import com.spikything.pants3d.events.PhysicsEvent;
	import com.spikything.pants3d.objects.Sprite3D;
	import flash.display.Sprite;
	
	public class PhysicsSprite3D extends Sprite3D {
		
		public var 		weightless 			:Boolean;
		public var 		frictionless 		:Boolean;
		public var 		ghostMode 			:Boolean;
		public var 		isContained 		:Boolean;
		public var 		w 					:Number;
		public var 		h  					:Number;
		public var 		d 					:Number;
		public var 		mass 				:Number;
		protected var 	internalFriction 	:Number;
		
		public function PhysicsSprite3D (x:Number=0, y:Number=0, z:Number=0, child:Sprite=null, width:Number=10, height:Number=10, depth:Number=10, weightless:Boolean=false, frictionless:Boolean=false, ghostMode:Boolean=false) {
			super(x, y, z, child);
			_id 				= "PhysicsSprite3D";
			w  					= width;
			h 					= height;
			d 					= depth;
			mass 				= w*h*d;
			this.weightless 	= weightless;
			this.frictionless 	= frictionless;
			this.ghostMode 		= ghostMode;
			isContained 		= true;
			internalFriction 	= 1;
			addEventListener(PhysicsEvent.COLLISION, onCollision, false, 0, true);
		}
		
		override public function toString ():String { return "PhysicsSprite3D" };
		override public function get isCollidable ():Boolean { return true };
		
		override public function impulse (ix:Number, iy:Number, iz:Number):void {
			vx += ix * internalFriction;
			vy += iy * internalFriction;
			vz += iz * internalFriction;
		}
		
		public function containsPoint (point:Point3D):Boolean {
			var dx:Number = px - point.px;
			var dy:Number = py - point.py;
			var dz:Number = pz - point.pz;
			return (Math.abs(dx)<=w/2 && Math.abs(dy)<=h/2 && Math.abs(dz)<=d/2);
		}
		
		public function applyForces (gravity:Number=0, fx:Number=0, fy:Number=0, fz:Number=0):void {
			if (!weightless) vy += gravity;// / Math.max(internalFriction, .1);
			vx += fx;
			vy += fy;
			vz += fz;
		}
		
		public function applyFriction (friction:Number):void {
			if (frictionless) return;
			vx *= friction * internalFriction;
			vy *= friction;// * internalFriction;
			vz *= friction * internalFriction;
		}
		
		// TODO handle collision, shunting passed sprite to surface and returning new vector?
		protected function onCollision (e:PhysicsEvent):void {
			trace(">> COLLISION: " + this.name + " and " + e.data.name);
			// work out collision angle for round objects and wall approach for square objects
		}
		
	}
	
}